﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Tridion.ContentManager.CoreService.Client;

namespace TridionDesktopTools.Core
{
    public partial class FieldMappingWindow
    {
        public string Host { private get; set; }
        public string Username { private get; set; }
        public string Password { private get; set; }

        public string SourceSchemaUri { private get; set; }
        public string TargetSchemaUri { private get; set; }
        public List<FieldMappingInfo> FieldMapping { get; private set; }

        private SchemaData _SourceSchema;

        private List<ItemFieldDefinitionData> _SourceSchemaFields;
        private List<ItemFieldDefinitionData> _TargetSchemaFields;

        public FieldMappingWindow()
        {
            InitializeComponent();
            this.dataGridFieldMapping.DataContext = this;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this._SourceSchema = (SchemaData)Functions.ReadItem(this.Host, this.Username, this.Password, this.SourceSchemaUri);

            this._SourceSchemaFields = Functions.GetSchemaFields(this.Host, this.Username, this.Password, this.SourceSchemaUri);
            this._SourceSchemaFields.Insert(0, new ItemFieldDefinitionData());

            this._TargetSchemaFields = Functions.GetSchemaFields(this.Host, this.Username, this.Password, this.TargetSchemaUri);

            if (this._SourceSchema.Purpose == SchemaPurpose.Embedded && this._TargetSchemaFields.Any(x => x.IsEmbedded()))
            {
                this._SourceSchemaFields.Add(new EmbeddedSchemaFieldDefinitionData { Name = "< parent source >", EmbeddedSchema = new LinkToSchemaData { IdRef = this._SourceSchema.Id, Title = this._SourceSchema.Title } });
            }

            this.FieldMapping = Functions.GetDefaultFieldMapping(this.Host, _SourceSchemaFields, _TargetSchemaFields, this.TargetSchemaUri);

            this.dataGridFieldMapping.ItemsSource = this.FieldMapping;
            ((DataGridComboBoxColumn)this.dataGridFieldMapping.Columns[1]).ItemsSource = this._SourceSchemaFields.Select(x => string.IsNullOrEmpty(x.Name) ? "< ignore >" : x.GetFieldFullName());

            Schema sourceSchema = Functions.GetSchemaData(this.Host, this.Username, this.Password, this.SourceSchemaUri);
            this.txtSourceSchema.Text = String.Format("Source Schema: {0} ({1})", sourceSchema.Title, sourceSchema.SchemaType);

            Schema targetSchema = Functions.GetSchemaData(this.Host, this.Username, this.Password, this.TargetSchemaUri);
            this.txtTargetSchema.Text = String.Format("Target Schema: {0} ({1})", targetSchema.Title, targetSchema.SchemaType);
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            if (this.Validate())
            {
                foreach (FieldMappingInfo mapping in this.FieldMapping)
                {
                    Functions.SaveToIsolatedStorage(this.Host + "_" + this.TargetSchemaUri.Replace("tcm:", "") + "_" + mapping.TargetField.Name, mapping.SourceField == null || string.IsNullOrEmpty(mapping.SourceField.Name) ? "< ignore >" : mapping.SourceField.Name);
                    Functions.SaveToIsolatedStorage(this.Host + "_" + this.TargetSchemaUri.Replace("tcm:", "") + "_" + mapping.TargetField.Name + "_DefaultValue", mapping.DefaultValue);
                }
                
                this.DialogResult = true;
                this.Close();
            }
            else
            {
                MessageBox.Show("Possible errors:\n\n" +
                                " - field types do not match\n" +
                                " - mapping for mandatory field is not selected and default value is not set"
                                , "Mapping Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private bool Validate()
        {
            return this.FieldMapping.Aggregate(true, (current, mappingInfo) => current && mappingInfo.Valid);
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.FieldMapping = null;
            this.Close();
        }

        private void btnMapping_OnClick(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            if (btn == null)
                return;

            string targetFieldName = btn.Tag.ToString();

            FieldMappingInfo fieldMapping = this.FieldMapping.FirstOrDefault(x => x.TargetFieldName == targetFieldName);
            if (fieldMapping == null)
                return;

            if (fieldMapping.Valid)
            {
                FieldMappingWindow dialog = new FieldMappingWindow();
                dialog.Host = this.Host;
                dialog.Username = this.Username;
                dialog.Password = this.Password;
                dialog.SourceSchemaUri = fieldMapping.SourceField.IsEmbedded() ? ((EmbeddedSchemaFieldDefinitionData)fieldMapping.SourceField).EmbeddedSchema.IdRef : ((ComponentLinkFieldDefinitionData)fieldMapping.SourceField).AllowedTargetSchemas[0].IdRef;
                dialog.TargetSchemaUri = fieldMapping.TargetField.IsEmbedded() ? ((EmbeddedSchemaFieldDefinitionData)fieldMapping.TargetField).EmbeddedSchema.IdRef : ((ComponentLinkFieldDefinitionData)fieldMapping.TargetField).AllowedTargetSchemas[0].IdRef;
                bool res = dialog.ShowDialog() == true;
                if (res)
                {
                    fieldMapping.ChildFieldMapping = dialog.FieldMapping;
                }
            }
        }

    }
}
